﻿using System;
using System.Collections.Generic;
using System.Web;
using System.DirectoryServices;
using System.Configuration;
using System.Data;

namespace Esint.Common
{
    /// <summary>
    ///ADHelper 的摘要说明
    /// </summary>
    public class ADHelper
    {
        ///
        ///域名
        ///
        //private static string DomainName = ConfigurationSettings.AppSettings["DomainName"].ToString();
        ///
        ///域名
        ///
        //private static string EmailName = "@" + ConfigurationSettings.AppSettings["DomainName"].ToString() + ".org";
        ///
        /// LDAP绑定路径
        ///
        //private static string ADPath = ConfigurationSettings.AppSettings["ADPath"].ToString();
        private static string ADPath = "LDAP://OU=esint network system,DC=esint,DC=com,DC=cn";
        ///
        ///登录帐号
        ///
        private static string ADUser = "weitong.liu";//ConfigurationSettings.AppSettings["ADUser"].ToString();
        ///
        ///登录密码
        ///
        private static string ADPassword = "00000000";//ConfigurationSettings.AppSettings["ADPassword"].ToString();
        ///
        ///初始化密码
        ///
        private static string InitializationPWD = "";// ConfigurationSettings.AppSettings["InitializationPWD"].ToString();
        ///
        ///用户添加的默认组
        ///
        private static string InitializationGROUP = ""; //ConfigurationSettings.AppSettings["InitializationGROUP"].ToString();

        ///
        ///用户登录验证结果
        ///
        public enum LoginResult
        {
            ///
            ///正常登录
            ///
            LOGIN_USER_OK = 0,
            ///
            ///用户不存在
            ///
            LOGIN_USER_DOESNT_EXIST,
            ///
            ///用户帐号被禁用
            ///
            LOGIN_USER_ACCOUNT_INACTIVE,
            ///
            ///用户密码不正确
            ///
            LOGIN_USER_PASSWORD_INCORRECT
        }

        ///
        ///用户属性定义标志
        ///
        public enum ADS_USER_FLAG_ENUM
        {
            ///
            ///登录脚本标志。如果通过 ADSI LDAP 进行读或写操作时，该标志失效。如果通过 ADSI WINNT，该标志为只读。
            ///
            ADS_UF_SCRIPT = 0X0001,
            ///
            ///用户帐号禁用标志
            ///
            ADS_UF_ACCOUNTDISABLE = 0X0002,
            ///
            ///主文件夹标志
            ///
            ADS_UF_HOMEDIR_REQUIRED = 0X0008,
            ///
            ///过期标志
            ///
            ADS_UF_LOCKOUT = 0X0010,
            ///
            ///用户密码不是必须的
            ///
            ADS_UF_PASSWD_NOTREQD = 0X0020,
            ///
            ///密码不能更改标志
            ///
            ADS_UF_PASSWD_CANT_CHANGE = 0X0040,
            ///
            ///使用可逆的加密保存密码
            ///
            ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0X0080,
            ///
            ///本地帐号标志
            ///
            ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0X0100,
            ///
            ///普通用户的默认帐号类型
            ///
            ADS_UF_NORMAL_ACCOUNT = 0X0200,
            ///
            ///跨域的信任帐号标志
            ///
            ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0X0800,
            ///
            ///工作站信任帐号标志
            ///
            ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000,
            ///
            ///服务器信任帐号标志
            ///
            ADS_UF_SERVER_TRUST_ACCOUNT = 0X2000,
            ///
            ///密码永不过期标志
            ///
            ADS_UF_DONT_EXPIRE_PASSWD = 0X10000,
            ///
            /// MNS 帐号标志
            ///
            ADS_UF_MNS_LOGON_ACCOUNT = 0X20000,
            ///
            ///交互式登录必须使用智能卡
            ///
            ADS_UF_SMARTCARD_REQUIRED = 0X40000,
            ///
            ///当设置该标志时，服务帐号（用户或计算机帐号）将通过 Kerberos 委托信任
            ///
            ADS_UF_TRUSTED_FOR_DELEGATION = 0X80000,
            ///
            ///当设置该标志时，即使服务帐号是通过 Kerberos 委托信任的，敏感帐号不能被委托
            ///
            ADS_UF_NOT_DELEGATED = 0X100000,
            ///
            ///此帐号需要 DES 加密类型
            ///
            ADS_UF_USE_DES_KEY_ONLY = 0X200000,
            ///
            ///不要进行 Kerberos 预身份验证
            ///
            ADS_UF_DONT_REQUIRE_PREAUTH = 0X4000000,
            ///
            ///用户密码过期标志
            ///
            ADS_UF_PASSWORD_EXPIRED = 0X800000,
            ///
            ///用户帐号可委托标志
            ///
            ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0X1000000
        }

        public ADHelper()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        #region GetDirectoryObject

        ///
        ///获得DirectoryEntry对象实例,以管理员登陆AD
        ///
        ///
        private static DirectoryEntry GetDirectoryObject()
        {
            DirectoryEntry entry = new DirectoryEntry(ADPath, ADUser, ADPassword, AuthenticationTypes.Secure);
            return entry;
        }


        ///
        ///根据指定用户名和密码获得相应DirectoryEntry实体
        ///
        ///
        ///
        ///
        private static DirectoryEntry GetDirectoryObject(string userName, string password)
        {
            DirectoryEntry entry = new DirectoryEntry(ADPath, userName, password, AuthenticationTypes.Secure);
            return entry;
        }

        ///
        /// i.e. /CN=Users,DC=creditsights, DC=cyberelves, DC=Com
        ///
        ///
        ///
        private static DirectoryEntry GetDirectoryObject(string domainReference)
        {
            DirectoryEntry entry = new DirectoryEntry(ADPath + domainReference, ADUser, ADPassword, AuthenticationTypes.Secure);
            return entry;
        }

        ///
        ///获得以UserName,Password创建的DirectoryEntry
        ///
        ///
        ///
        ///
        ///
        private static DirectoryEntry GetDirectoryObject(string domainReference, string userName, string password)
        {
            DirectoryEntry entry = new DirectoryEntry(ADPath + domainReference, userName, password, AuthenticationTypes.Secure);
            return entry;
        }
        #endregion

        #region GroupDataTable

        /// <summary>
        /// 查询组信息
        /// </summary>
        /// <param name="strGroupName"></param>
        /// <param name="strDescription"></param>
        /// <returns></returns>
        public static DataTable FindGroups(string strGroupName, string strDescription)
        {
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);
            deSearch.Filter = "(&(objectClass=group))";
            if (!string.IsNullOrEmpty(strGroupName))
                deSearch.Filter = "(&" + deSearch.Filter + "(sAMAccountName=*" + strGroupName + "*))";
            if (!string.IsNullOrEmpty(strDescription))
                deSearch.Filter = "(&" + deSearch.Filter + "(description=*" + strDescription + "*))";

            try
            {
                SearchResultCollection srColl = deSearch.FindAll();
                DataTable dt = new DataTable("DirectoryEntryColl");
                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (SearchResult sr in srColl)
                {
                    dr = dt.NewRow();
                    de = sr.GetDirectoryEntry();
                    dr["GUID"] = de.Guid.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();
                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";
                    dt.Rows.Add(dr);
                }
                return dt;
            }
            catch
            {
                return null;
            }
        }

        public static DataTable FindGroupsByUser(string strName, string strGroupName, string strChName)
        {
            try
            {
                DirectoryEntry rootEntry = GetDirectoryObject();
                DirectorySearcher deSearch = new DirectorySearcher(rootEntry);
                deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + strName + "))";

                SearchResult result = deSearch.FindOne();
                DirectoryEntry diren = result.GetDirectoryEntry();

                DataTable dt = new DataTable("DirectoryEntryColl");

                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (object o in diren.Properties["memberOf"])
                {
                    dr = dt.NewRow();
                    string[] s = o.ToString().Split(',');

                    de = rootEntry.Children.Find(s[0].ToString(), "group");


                    dr["GUID"] = de.Guid.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();
                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";

                    dt.Rows.Add(dr);
                }
                dt.DefaultView.RowFilter = "sAMAccountName like '%" + strGroupName + "%' and description like '%" + strChName + "%'";
                return dt;
            }
            catch
            {
                return null;
            }
        }

        public static DataTable FindNotInGroupsByUser(string userName, string groupName, string description)
        {
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);

            deSearch.Filter = "(&(objectClass=group))";
            if (!string.IsNullOrEmpty(groupName))
                deSearch.Filter = "(&" + deSearch.Filter + "(sAMAccountName=*" + groupName + "*))";
            if (!string.IsNullOrEmpty(description))
                deSearch.Filter = "(&" + deSearch.Filter + "(description=*" + description + "*))";

            DirectoryEntry oUser = GetDirectoryEntry(userName);
            try
            {
                SearchResultCollection srColl = deSearch.FindAll();
                DataTable dt = new DataTable("DirectoryEntryColl");
                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                string str = "";
                foreach (SearchResult sr in srColl)
                {
                    dr = dt.NewRow();
                    de = sr.GetDirectoryEntry();
                    str = "0";
                    foreach (object o in oUser.Properties["memberOf"])
                    {
                        if (o.ToString() == de.Properties["distinguishedName"].Value.ToString())
                        {
                            str = "1";
                            break;
                        }
                    }
                    if (str == "0")
                    {
                        dr["GUID"] = de.Guid.ToString();
                        if (de.Properties["sAMAccountName"].Value != null)
                            dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();
                        if (de.Properties["description"].Value != null)
                            dr["description"] = de.Properties["description"].Value.ToString();
                        else
                            dr["description"] = "";
                        dt.Rows.Add(dr);
                    }
                }
                return dt;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 添加组
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public static bool AddGroup(string strName, string description)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryObject();

                DirectoryEntry newEntry;
                string entryName = "Cn=" + strName;
                newEntry = entry.Children.Add(entryName, "group");
                newEntry.UsePropertyCache = true;
                // 组名
                newEntry.Properties["sAMAccountName"].Value = strName.Trim();

                // 描述
                if (!string.IsNullOrEmpty(description))
                    newEntry.Properties["description"].Add(description.Trim());


                newEntry.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool AddGroupForUser(string strName, string groupName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry oUser = GetDirectoryEntry(strName);
                DirectoryEntry oGroup;
                string[] strGroupNames = groupName.Split(';');
                foreach (string gName in strGroupNames)
                {
                    oGroup = GetDirectoryEntryFromGroup(gName);
                    oGroup.Properties["member"].Add(oUser.Properties["distinguishedName"].Value);
                    oGroup.CommitChanges();
                }
                oUser.Close();


                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool UpdateGroup(string oldGroupName, string newGroupName, string description)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryEntryFromGroup(oldGroupName);

                // 用户登录名
                entry.Properties["sAMAccountName"].Value = newGroupName;

                // 描述
                if (!string.IsNullOrEmpty(description))
                    entry.Properties["description"].Value = description;
                else
                    entry.Properties["description"].Value = null;

                entry.CommitChanges();

                entry.Rename("CN=" + newGroupName);
                entry.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 删除组信息
        /// </summary>
        /// <param name="strName"></param>
        /// <returns></returns>
        public static bool DelGroup(string strName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry de = GetDirectoryObject();
                string entryName = "Cn=" + strName;
                DirectoryEntry delete = de.Children.Find(entryName, "group");

                de.Children.Remove(delete);
                de.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        #region UserDataTable

        /// <summary>
        /// 按sAMAccountName(账号)load用户
        /// </summary>
        /// <param name="strName">账号</param>
        /// <returns></returns>
        public static DataTable LoadUser(string strName)
        {
            if (string.IsNullOrEmpty(strName))
            {
                return null;
            }
            DataTable userTable = new DataTable("DirectoryEntryColl");
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);
            deSearch.Filter = "(&(objectCategory=person)(objectClass=user))";
            deSearch.Filter = "(&" + deSearch.Filter + "(sAMAccountName=" + strName + "))";
            try
            {
                SearchResultCollection srColl = deSearch.FindAll();
                userTable.Columns.Add("GUID", typeof(string));
                userTable.Columns.Add("sAMAccountName", typeof(string));
                userTable.Columns.Add("displayName", typeof(string));
                userTable.Columns.Add("description", typeof(string));
                userTable.Columns.Add("userAccountControl", typeof(string));
                userTable.Columns.Add("distinguishedName", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (SearchResult sr in srColl)
                {

                    dr = userTable.NewRow();
                    de = sr.GetDirectoryEntry();
                    string sFlag = "";
                    dr["GUID"] = de.Guid.ToString();
                    dr["distinguishedName"] = de.Properties["distinguishedName"].Value.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();

                    if (de.Properties["displayName"].Value != null)
                        dr["displayName"] = de.Properties["displayName"].Value.ToString();
                    else
                        dr["displayName"] = "";

                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";

                    if (de.Properties["userAccountControl"].Value != null)
                    {
                        dr["userAccountControl"] = de.Properties["userAccountControl"].Value.ToString();
                        if (ADHelper.IsAccountActive(int.Parse(dr["userAccountControl"].ToString())))
                            sFlag = "1";
                        else
                            sFlag = "0";
                    }

                    userTable.Rows.Add(dr);
                }
            }
            catch
            {
                return null;
            }

            return userTable;
        }

        /// <summary>
        /// 查找用户信息
        /// </summary>
        /// <param name="strName">账户名</param>
        /// <param name="strChName">用户全名</param>
        /// <param name="strState">用户状态</param>
        /// <returns></returns>
        public static DataTable FindUsers(string strName, string strChName, string strState)
        {
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);

            //deSearch.Filter = "(&(objectCategory=person)(objectClass=user))";
            deSearch.Filter = "((objectClass=user))";
            if (!string.IsNullOrEmpty(strName))
                deSearch.Filter = "(&" + deSearch.Filter + "(sAMAccountName=*" + strName + "*))";
            if (!string.IsNullOrEmpty(strChName))
                deSearch.Filter = "(&" + deSearch.Filter + "(displayName=*" + strChName + "*))";

            try
            {
                SearchResultCollection srColl = deSearch.FindAll();
                DataTable dt = new DataTable("DirectoryEntryColl");
                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("displayName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                dt.Columns.Add("userAccountControl", typeof(string));
                dt.Columns.Add("distinguishedName", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (SearchResult sr in srColl)
                {

                    dr = dt.NewRow();
                    de = sr.GetDirectoryEntry();
                    string sFlag = "";
                    dr["GUID"] = de.Guid.ToString();
                    dr["distinguishedName"] = de.Properties["distinguishedName"].Value.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();

                    if (de.Properties["displayName"].Value != null)
                        dr["displayName"] = de.Properties["displayName"].Value.ToString();
                    else
                        dr["displayName"] = "";

                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";

                    if (de.Properties["userAccountControl"].Value != null)
                    {
                        dr["userAccountControl"] = de.Properties["userAccountControl"].Value.ToString();
                        if (ADHelper.IsAccountActive(int.Parse(dr["userAccountControl"].ToString())))
                            sFlag = "1";
                        else
                            sFlag = "0";
                    }


                    if (string.IsNullOrEmpty(strState))
                    {
                        dt.Rows.Add(dr);
                    }
                    else
                    {
                        if (strState == sFlag)
                            dt.Rows.Add(dr);
                    }
                }
                return dt;
            }
            catch
            {

                return null;
            }
        }

        /// <summary>
        /// 查找用户
        /// </summary>
        /// <param name="strName">是distinguishedName活动目录节点名</param>
        /// <returns></returns>
        public static DataTable FindUsers(string strName)
        {
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);

            deSearch.Filter = "(&(objectCategory=person)(objectClass=user))";

            deSearch.Filter = "(&" + deSearch.Filter + "(distinguishedName=*" + strName + "*))";

            try
            {
                SearchResult result = deSearch.FindOne();
                DirectoryEntry diren = new DirectoryEntry(result.Path);


                DataTable dt = new DataTable("DirectoryEntryColl");

                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("displayName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                dt.Columns.Add("userAccountControl", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (object o in diren.Properties["member"])
                {
                    dr = dt.NewRow();
                    string[] s = o.ToString().Split(',');


                    de = rootEntry.Children.Find(s[0].ToString(), "user");


                    dr["GUID"] = de.Guid.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();

                    if (de.Properties["displayName"].Value != null)
                        dr["displayName"] = de.Properties["displayName"].Value.ToString();
                    else
                        dr["displayName"] = "";

                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";

                    if (de.Properties["userAccountControl"].Value != null)
                        dr["userAccountControl"] = de.Properties["userAccountControl"].Value.ToString();

                    dt.Rows.Add(dr);
                }

                return dt;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 查找组中的人员
        /// </summary>
        /// <param name="strGroupName"></param>
        /// <param name="strName"></param>
        /// <param name="strChName"></param>
        /// <returns></returns>
        public static DataTable FindUsersFromGroup(string strGroupName, string strName, string strChName)
        {
            try
            {
                DirectoryEntry rootEntry = GetDirectoryObject();
                DirectorySearcher deSearch = new DirectorySearcher(rootEntry);
                deSearch.Filter = "(&(objectClass=group)(sAMAccountName=" + strGroupName + "))";

                SearchResult result = deSearch.FindOne();
                DirectoryEntry diren = new DirectoryEntry(result.Path);

                DataTable dt = new DataTable("DirectoryEntryColl");

                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("displayName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                dt.Columns.Add("userAccountControl", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                foreach (object o in diren.Properties["member"])
                {
                    dr = dt.NewRow();
                    string[] s = o.ToString().Split(',');


                    de = rootEntry.Children.Find(s[0].ToString(), "user");


                    dr["GUID"] = de.Guid.ToString();
                    if (de.Properties["sAMAccountName"].Value != null)
                        dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();

                    if (de.Properties["displayName"].Value != null)
                        dr["displayName"] = de.Properties["displayName"].Value.ToString();
                    else
                        dr["displayName"] = "";

                    if (de.Properties["description"].Value != null)
                        dr["description"] = de.Properties["description"].Value.ToString();
                    else
                        dr["description"] = "";

                    if (de.Properties["userAccountControl"].Value != null)
                        dr["userAccountControl"] = de.Properties["userAccountControl"].Value.ToString();

                    dt.Rows.Add(dr);
                }
                dt.DefaultView.RowFilter = " sAMAccountName like '%" + strName + "%' and displayName like '%" + strChName + "%'";
                return dt;
            }
            catch
            {
                return null;
            }
        }

        public static DataTable FindUsersNotInGroup(string groupName, string strName, string strChName)
        {
            DirectoryEntry rootEntry = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(rootEntry);
            deSearch.Filter = "(&(objectCategory=person)(objectClass=user))";
            if (!string.IsNullOrEmpty(strName))
                deSearch.Filter = "(&" + deSearch.Filter + "(sAMAccountName=*" + strName + "*))";
            if (!string.IsNullOrEmpty(strChName))
                deSearch.Filter = "(&" + deSearch.Filter + "(displayName=*" + strChName + "*))";

            DirectoryEntry oGroup = GetDirectoryEntryFromGroup(groupName);
            try
            {
                SearchResultCollection srColl = deSearch.FindAll();
                DataTable dt = new DataTable("DirectoryEntryColl");
                dt.Columns.Add("GUID", typeof(string));
                dt.Columns.Add("sAMAccountName", typeof(string));
                dt.Columns.Add("displayName", typeof(string));
                dt.Columns.Add("description", typeof(string));
                dt.Columns.Add("userAccountControl", typeof(string));
                DataRow dr;
                DirectoryEntry de;
                string str = "";
                foreach (SearchResult sr in srColl)
                {
                    dr = dt.NewRow();
                    de = sr.GetDirectoryEntry();
                    str = "0";
                    foreach (object o in oGroup.Properties["member"])
                    {
                        if (o.ToString() == de.Properties["distinguishedName"].Value.ToString())
                        {
                            str = "1";
                            break;
                        }
                    }
                    if (str == "0")
                    {
                        dr["GUID"] = de.Guid.ToString();
                        if (de.Properties["sAMAccountName"].Value != null)
                            dr["sAMAccountName"] = de.Properties["sAMAccountName"].Value.ToString();

                        if (de.Properties["displayName"].Value != null)
                            dr["displayName"] = de.Properties["displayName"].Value.ToString();
                        else
                            dr["displayName"] = "";

                        if (de.Properties["description"].Value != null)
                            dr["description"] = de.Properties["description"].Value.ToString();
                        else
                            dr["description"] = "";

                        if (de.Properties["userAccountControl"].Value != null)
                            dr["userAccountControl"] = de.Properties["userAccountControl"].Value.ToString();
                        dt.Rows.Add(dr);
                    }
                }
                return dt;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 初始化用户密码
        /// </summary>
        /// <param name="strName"></param>
        /// <returns></returns>
        public static bool ReUserPassWord(string strName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryEntry(strName);


                entry.Invoke("SetPassword", new object[] { InitializationPWD });
                entry.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 用户修改密码
        /// </summary>
        /// <param name="strName"></param>
        /// <returns></returns>
        public static bool UserChangePassWord(string strName, string strPWD)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryEntry(strName);


                entry.Invoke("SetPassword", new object[] { strPWD });
                entry.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="strChName"></param>
        /// <param name="description"></param>
        /// <param name="passWord"></param>
        /// <returns></returns>
        public static bool AddUserAccount(string strName, string strChName, string description)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryObject();

                DirectoryEntry newEntry;
                string entryName = "Cn=" + strChName;
                newEntry = entry.Children.Add(entryName, "user");
                newEntry.UsePropertyCache = true;
                // 用户登录名
                newEntry.Properties["sAMAccountName"].Value = strName.Trim();
                //newEntry.Properties["userPrincipalName"].Add(strName.Trim() + EmailName);

                // 显示名称
                if (!string.IsNullOrEmpty(strChName))
                    newEntry.Properties["displayName"].Add(strChName.Trim());

                // 描述
                if (!string.IsNullOrEmpty(description))
                    newEntry.Properties["description"].Add(description.Trim());

                DirectoryEntry oGroup = GetDirectoryEntryFromGroup(InitializationGROUP);
                //oGroup.Properties["member"].Add(oUser.Properties["distinguishedName"].Value);

                //newEntry.Properties["memberOf"].Add(oGroup.Properties["distinguishedName"].Value);            

                newEntry.CommitChanges();

                //oGroup.Properties["member"].Add(newEntry.Properties["distinguishedName"].Value);
                //oGroup.CommitChanges();

                //newEntry.Properties["userAccountControl"].Value = 66048;

                newEntry.Invoke("SetPassword", new object[] { InitializationPWD });
                newEntry.Properties["userAccountControl"].Value = 66048;
                //newEntry.Properties["userAccountControl"].Value = 544;
                //newEntry.Properties["pwdLastSet"].Value = 0;           

                newEntry.CommitChanges();



                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool UpdateUserAccount(string oldUserName, string newUserName, string displayName, string description)
        {
            bool flag = false;
            try
            {
                DirectoryEntry entry = GetDirectoryEntry(oldUserName);

                // 用户登录名
                //entry.Properties["sAMAccountName"].Value = newUserName;

                if (!string.IsNullOrEmpty(displayName))
                    entry.Properties["displayName"].Value = displayName;
                else
                    entry.Properties["displayName"].Value = null;

                // 描述
                if (!string.IsNullOrEmpty(description))
                    entry.Properties["description"].Value = description;
                else
                    entry.Properties["description"].Value = null;

                entry.CommitChanges();

                //entry.Rename("CN=" + displayName);
                entry.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool AddUserToGroup(string groupName, string strName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry oGroup = GetDirectoryEntryFromGroup(groupName);
                DirectoryEntry oUser;
                string[] strUserNames = strName.Split(';');
                foreach (string uname in strUserNames)
                {
                    oUser = GetDirectoryEntry(uname);
                    oGroup.Properties["member"].Add(oUser.Properties["distinguishedName"].Value);
                }
                oGroup.CommitChanges();
                oGroup.Close();


                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool DelUserAccount(string strName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry de = GetDirectoryObject();
                //string entryName = "Cn=" + strName;
                DirectorySearcher searcher = new DirectorySearcher(de);
                searcher.Filter = "sAMAccountName=" + strName;
                SearchResult sr = searcher.FindOne();
                sr.GetDirectoryEntry().DeleteTree();


                //DirectoryEntry delete = de.Children.Find(entryName, "user");

                //de.Children.Remove(delete);
                //de.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        public static bool DelUserFromGroup(string groupName, string userName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry oGroup = GetDirectoryEntryFromGroup(groupName);
                DirectoryEntry oUser = GetDirectoryEntry(userName);


                oGroup.Properties["member"].Remove(oUser.Properties["distinguishedName"].Value);
                oGroup.CommitChanges();


                oGroup.Close();
                oUser.Close();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        #region GetDirectoryEntry

        public static bool UserSetState(string userName)
        {
            bool flag = false;
            try
            {
                DirectoryEntry de = GetDirectoryObject();
                DirectorySearcher deSearch = new DirectorySearcher(de);
                deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + userName + "))";

                SearchResult result = deSearch.FindOne();
                de = result.GetDirectoryEntry();

                de.Properties["userAccountControl"].Value = ((Int32.Parse(de.Properties["userAccountControl"].Value.ToString())) ^ (Int32.Parse("2")));

                de.CommitChanges();
                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }
        }

        ///
        ///根据用户公共名称取得用户的 对象
        ///
        ///用户公共名称 
        ///如果找到该用户，则返回用户的 对象；否则返回 null
        public static DirectoryEntry GetDirectoryEntry(string commonName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + commonName + "))";
            //deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";
            //deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                de = result.GetDirectoryEntry();
                //de = new DirectoryEntry(result.Path);
                return de;
            }
            catch
            {
                return null;
            }
        }

        public static DirectoryEntry GetDirectoryEntryFromGroup(string commonName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(objectClass=group)(sAMAccountName=" + commonName + "))";
            //deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";
            deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                return result.GetDirectoryEntry();
            }
            catch
            {
                return null;
            }
        }


        ///
        ///根据用户公共名称和密码取得用户的 对象。
        ///
        ///用户公共名称 
        ///用户密码 
        ///如果找到该用户，则返回用户的 对象；否则返回 null
        public static DirectoryEntry GetDirectoryEntry(string commonName, string password)
        {
            DirectoryEntry de = GetDirectoryObject(commonName, password);
            //DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";
            deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                de = new DirectoryEntry(result.Path);
                return de;
            }
            catch
            {
                return null;
            }
        }
        public static DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName, string password)
        {
            DirectoryEntry de = GetDirectoryObject(sAMAccountName, password);
            //DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + sAMAccountName + "))";
            deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                de = new DirectoryEntry(result.Path);
                return de;
            }
            catch
            {
                return null;
            }
        }

        ///
        ///根据用户帐号称取得用户的 对象
        ///
        ///用户帐号名 
        ///如果找到该用户，则返回用户的 对象；否则返回 null
        public static DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + sAMAccountName + "))";
            deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                de = new DirectoryEntry(result.Path);
                return de;
            }
            catch
            {
                return null;
            }
        }

        ///
        ///根据用户帐号和密码取得用户的 对象
        ///
        ///用户帐号名 
        ///用户密码 
        ///如果找到该用户，则返回用户的 对象；否则返回 null
        public static DirectoryEntry GetDirectoryEntryByAccount1(string sAMAccountName, string password)
        {
            DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);
            if (de != null)
            {
                //string commonName = de.Properties["cn"][0].ToString();
                DirectoryEntry userDe = GetDirectoryEntry(sAMAccountName, password);
                //DirectoryEntry userDe = GetDirectoryObject(sAMAccountName, password);
                if (userDe != null)
                    return userDe;
                // return GetDirectoryEntry(sAMAccountName, password);
                else
                    return null;
            }
            else
            {
                return null;
            }
        }

        ///
        ///根据组名取得用户组的 对象
        ///
        ///组名 
        ///
        public static DirectoryEntry GetDirectoryEntryOfGroup(string groupName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(objectClass=group)(cn=" + groupName + "))";
            deSearch.SearchScope = SearchScope.Subtree;

            try
            {
                SearchResult result = deSearch.FindOne();
                de = new DirectoryEntry(result.Path);
                return de;
            }
            catch
            {
                return null;
            }
        }

        #endregion

        #region GetProperty

        ///
        ///获得指定 指定属性名对应的值
        ///
        ///
        ///属性名称 
        ///属性值
        public static string GetProperty(DirectoryEntry de, string propertyName)
        {
            if (de.Properties.Contains(propertyName))
            {
                return de.Properties[propertyName][0].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

        ///
        ///获得指定搜索结果 中指定属性名对应的值
        ///
        ///
        ///属性名称 
        ///属性值
        public static string GetProperty(SearchResult searchResult, string propertyName)
        {
            if (searchResult.Properties.Contains(propertyName))
            {
                return searchResult.Properties[propertyName][0].ToString();
            }
            else
            {
                return string.Empty;
            }
        }

        #endregion

        #region  SetProperty
        ///设置指定 的属性值
        ///属性名称 
        ///属性值 
        public static void SetProperty(DirectoryEntry de, string propertyName, string propertyValue)
        {
            if (propertyValue != string.Empty || propertyValue != "" || propertyValue != null)
            {
                if (de.Properties.Contains(propertyName))
                {
                    de.Properties[propertyName][0] = propertyValue;
                }
                else
                {
                    de.Properties[propertyName].Add(propertyValue);
                }
            }
        }
        #endregion

        #region  创建新的用户
        ///创建新的用户
        ///DN 位置。例如：OU=共享平台 或 CN=Users 
        ///公共名称 
        ///帐号 
        ///密码 
        public static DirectoryEntry CreateNewUser(string ldapDN, string commonName, string sAMAccountName, string password)
        {
            DirectoryEntry entry = GetDirectoryObject();
            DirectoryEntry subEntry = entry.Children.Find(ldapDN);
            DirectoryEntry deUser = subEntry.Children.Add("CN=" + commonName, "user");
            deUser.Properties["sAMAccountName"].Value = sAMAccountName;
            deUser.CommitChanges();
            ADHelper.EnableUser(commonName);
            ADHelper.SetPassword(commonName, password);
            deUser.Close();
            return deUser;
        }

        ///创建新的用户。默认创建在 Users 单元下。
        ///公共名称 
        ///帐号 
        ///密码 
        public static DirectoryEntry CreateNewUser(string commonName, string sAMAccountName, string password)
        {
            return CreateNewUser("CN=Users", commonName, sAMAccountName, password);
        }
        #endregion

        #region 验证用户
        ///判断指定公共名称的用户是否存在
        ///用户公共名称 
        ///如果存在，返回 true；否则返回 false
        public static bool IsUserExists(string commonName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + commonName + "))";       // LDAP 查询串
            SearchResultCollection results = deSearch.FindAll();

            if (results.Count == 0)
                return false;
            else
                return true;
        }

        /// <summary>
        /// 判断指定中文名称的用户是否存在
        /// </summary>
        /// <param name="commonName">中文名</param>
        /// <returns></returns>
        public static bool IsUserExistsByCNName(string cnName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + cnName + "))";       // LDAP 查询串
            SearchResultCollection results = deSearch.FindAll();

            if (results.Count == 0)
                return false;
            else
                return true;
        }

        /// <summary>
        /// 判断指定显示名称的用户是否存在
        /// </summary>
        /// <param name="commonName">中文名</param>
        /// <returns></returns>
        public static bool IsUserExistsByDisplayName(string commonName, string displayName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(&(&(objectCategory=person)(objectClass=user))(sAMAccountName!=" + commonName + "))(cn=" + displayName + "))";
            //deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(displayName=" + displayName + "))";       // LDAP 查询串
            SearchResultCollection results = deSearch.FindAll();

            if (results.Count == 0)
                return false;
            else
                return true;
        }

        ///判断用户帐号是否激活
        ///用户帐号属性控制器 
        ///如果用户帐号已经激活，返回 true；否则返回 false
        public static bool IsAccountActive(int userAccountControl)
        {
            int userAccountControl_Disabled = Convert.ToInt32(ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE);
            int flagExists = userAccountControl & userAccountControl_Disabled;

            if (flagExists > 0)
                return false;
            else
                return true;
        }
        #endregion

        #region  验证用户组
        public static bool IsGroupExists(string commonName)
        {
            DirectoryEntry de = GetDirectoryObject();
            DirectorySearcher deSearch = new DirectorySearcher(de);
            deSearch.Filter = "(&(objectClass=group)(sAMAccountName=" + commonName + "))";       // LDAP 查询串
            SearchResultCollection results = deSearch.FindAll();

            if (results.Count == 0)
                return false;
            else
                return true;
        }
        #endregion

        #region 登录验证

        ///判断用户与密码是否足够以满足身份验证进而登录
        ///用户公共名称 
        ///密码 
        ///如能可正常登录，则返回 true；否则返回 false
        public static LoginResult Login(string commonName, string password)
        {
            DirectoryEntry de = GetDirectoryEntry(commonName);

            if (de != null)
            {
                // 必须在判断用户密码正确前，对帐号激活属性进行判断；否则将出现异常。
                //int userAccountControl = Convert.ToInt32(de.Properties["userAccountControl"][0]);
                de.Close();

                //if (!IsAccountActive(userAccountControl))
                //    return LoginResult.LOGIN_USER_ACCOUNT_INACTIVE;

                if (GetDirectoryEntry(commonName, password) != null)
                    return LoginResult.LOGIN_USER_OK;
                else
                    return LoginResult.LOGIN_USER_PASSWORD_INCORRECT;
            }
            else
            {
                return LoginResult.LOGIN_USER_DOESNT_EXIST;
            }
        }

        ///判断用户帐号与密码是否足够以满足身份验证进而登录
        ///用户帐号 
        ///密码 
        ///如能可正常登录，则返回 true；否则返回 false
        public static LoginResult LoginByAccount(string sAMAccountName, string password)
        {
            DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);

            if (de != null)
            {
                // 必须在判断用户密码正确前，对帐号激活属性进行判断；否则将出现异常。
                //int userAccountControl = Convert.ToInt32(de.Properties["userAccountControl"][0]);
                de.Close();

                //if (!IsAccountActive(userAccountControl))
                //    return LoginResult.LOGIN_USER_ACCOUNT_INACTIVE;

                if (GetDirectoryEntryByAccount(sAMAccountName, password) != null)
                    return LoginResult.LOGIN_USER_OK;
                else
                    return LoginResult.LOGIN_USER_PASSWORD_INCORRECT;
            }
            else
            {
                return LoginResult.LOGIN_USER_DOESNT_EXIST;
            }
        }
        #endregion

        #region 修改用户密码
        ///设置用户密码，管理员可以通过它来修改指定用户的密码。
        ///用户公共名称 
        ///用户新密码 
        public static void SetPassword(string commonName, string newPassword)
        {
            //DirectoryEntry de = GetDirectoryEntry(commonName);

            //IdentityImpersonation impersonate = new IdentityImpersonation(ADUser, ADPassword, DomainName);
            //// 模拟超级管理员，以达到有权限修改用户密码
            //impersonate.BeginImpersonate();
            //de.Invoke("SetPassword", new object[] { newPassword });
            //impersonate.StopImpersonate();

            //de.Close();
        }

        ///设置帐号密码，管理员可以通过它来修改指定帐号的密码。
        ///用户帐号 
        ///用户新密码 
        public static void SetPasswordByAccount(string sAMAccountName, string newPassword)
        {
            //DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);

            //// 模拟超级管理员，以达到有权限修改用户密码
            //IdentityImpersonation impersonate = new IdentityImpersonation(ADUser, ADPassword, DomainName);
            //impersonate.BeginImpersonate();
            //de.Invoke("SetPassword", new object[] { newPassword });
            //impersonate.StopImpersonate();

            //de.Close();
        }

        ///修改用户密码
        ///用户公共名称 
        ///旧密码 
        ///新密码 
        public static bool ChangeUserPassword(string commonName, string oldPassword, string newPassword)
        {
            bool flag = false;
            try
            {
                DirectoryEntry oUser = GetDirectoryEntry(commonName);
                oUser.Invoke("ChangePassword", new Object[] { oldPassword, newPassword });
                oUser.CommitChanges();

                flag = true;
                return flag;
            }
            catch
            {
                return false;
            }

        }
        #endregion

        #region 开通、禁用用户
        ///启用指定公共名称的用户
        ///用户公共名称 
        public static void EnableUser(string commonName)
        {
            EnableUser(GetDirectoryEntry(commonName));
        }

        ///启用指定 的用户
        public static void EnableUser(DirectoryEntry de)
        {
            //impersonate.BeginImpersonate();
            //de.Properties["userAccountControl"][0] = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD;
            //de.CommitChanges();
            //impersonate.StopImpersonate();
            //de.Close();
        }

        ///禁用指定公共名称的用户
        ///用户公共名称 
        public static void DisableUser(string commonName)
        {
            DisableUser(GetDirectoryEntry(commonName));
        }

        ///禁用指定 的用户
        public static void DisableUser(DirectoryEntry de)
        {
            //impersonate.BeginImpersonate();
            //de.Properties["userAccountControl"][0] = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE;
            //de.CommitChanges();
            //impersonate.StopImpersonate();
            //de.Close();
        }
        #endregion

    }
}